#include "serialcontrol.h"

#include <QtSerialPort/QSerialPortInfo>
#include <QDebug>

SerialControl::SerialControl(QObject* parent)
    : QObject(parent),
      serialPort(nullptr)
{
    parser[UpTime] = &SerialControl::parseUpTime;
    parser[DownTime] = &SerialControl::parseDownTime;
    parser[MaxTransmit] = &SerialControl::parseMaxTransmit;
    parser[MinTransmit] = &SerialControl::parseMinTransmit;
    parser[RuntimeTransmit] = &SerialControl::parseRuntimeTransmit;
    parser[TransmitCurve] = &SerialControl::parseTransmitCurve;
}

QVector<QPair<QString, QString>> SerialControl::getSerialPortList()
{
    QVector<QPair<QString, QString>> portNameList;
    for (auto& info : QSerialPortInfo::availablePorts()) {
        portNameList.push_back({info.portName(), info.description()});
    }
    return portNameList;
}

bool SerialControl::open(const QString& portName)
{
    serialPort = new QSerialPort(portName);
    bool ok = serialPort->open(QIODevice::ReadWrite);
    if (!ok) {
        delete serialPort;
        return false;
    }

    serialPort->setBaudRate(QSerialPort::Baud115200);
    serialPort->setDataBits(QSerialPort::Data8);
    serialPort->setParity(QSerialPort::NoParity);
    serialPort->setStopBits(QSerialPort::OneStop);
    serialPort->setFlowControl(QSerialPort::NoFlowControl);

    connect(serialPort, &QSerialPort::readyRead, this, &SerialControl::receive);

    return true;
}

void SerialControl::close()
{
    if (serialPort == nullptr) {
        return;
    }
    serialPort->clear();
    serialPort->close();
    delete serialPort;
}

void SerialControl::receive()
{
    QByteArray byteArray = serialPort->readAll();
    qDebug()<<byteArray.toHex();
    recvBytes += byteArray;
    if (recvBytes.size() < 4 || int(recvBytes[3]) + 5 != recvBytes.size()) {
        serialPort->clear();
        return;
    }
    (this->*parser[FrameType((int)recvBytes[2])])(recvBytes);
    recvBytes.clear();
}

void SerialControl::parseUpTime(const QByteArray &byteArray)
{
    double upTime = parseRealValue(byteArray);
    emit received(UpTime, {upTime});
}

void SerialControl::parseDownTime(const QByteArray &byteArray)
{
    double downTime = parseRealValue(byteArray);
    emit received(DownTime, {downTime});
}

void SerialControl::parseMaxTransmit(const QByteArray &byteArray)
{
    double maxTransmit = parseRealValue(byteArray);
    emit received(MaxTransmit, {maxTransmit});
}

void SerialControl::parseMinTransmit(const QByteArray &byteArray)
{
    double minTransmit = parseRealValue(byteArray);
    emit received(MinTransmit, {minTransmit});
}

void SerialControl::parseRuntimeTransmit(const QByteArray &byteArray)
{
    double runtimeTransmit = parseRealValue(byteArray);
    emit received(RuntimeTransmit, {runtimeTransmit});
}

void SerialControl::parseTransmitCurve(const QByteArray &byteArray)
{
    QVector<double> transmitCurveValue;
    for (auto iter = byteArray.begin() + 4; iter != byteArray.end() - 1; ++iter) {
        transmitCurveValue.push_back(*iter);
    }
    emit received(TransmitCurve, transmitCurveValue);
}

double SerialControl::parseRealValue(const QByteArray &byteArray)
{
    QByteArray valueByte;
    for (auto iter = byteArray.begin() + 4; iter != byteArray.end() - 1; ++iter) {
        valueByte.push_back(*iter);
    }

    return QString(valueByte).toDouble();
}
